package net.csdn.business.discuss.api.service.impl;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import net.csdn.business.discuss.api.config.ApiConfigData;
import net.csdn.business.discuss.api.enums.DiscussActionEventEnum;
import net.csdn.business.discuss.api.mapper.DiscussMapper;
import net.csdn.business.discuss.api.model.dto.*;
import net.csdn.business.discuss.api.model.entity.Discuss;
import net.csdn.business.discuss.api.model.query.*;
import net.csdn.business.discuss.api.model.vo.*;
import net.csdn.business.discuss.api.service.*;
import net.csdn.business.discuss.common.config.AsyncThreadPoolConfig;
import net.csdn.business.discuss.common.constant.RedisConstants;
import net.csdn.business.discuss.common.enums.DiscussStateEnum;
import net.csdn.business.discuss.common.enums.ResultCodeEnum;
import net.csdn.business.discuss.common.exception.BusinessException;
import net.csdn.business.discuss.common.model.dto.UserRoleDto;
import net.csdn.business.discuss.common.model.vo.UserInfoVO;
import net.csdn.business.discuss.feign.api.OrgFeignClient;
import net.csdn.business.discuss.feign.api.ProjectFeignClient;
import net.csdn.business.discuss.feign.api.UserFeignClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.Cache;
import org.springframework.cache.CacheManager;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.*;


/**
 * @ClassName DiscussServiceImpl
 * @Description 讨论Service业务层处理
 * @Author zhangyl
 * @Date 2023/7/18 11:24 
 */
@Slf4j
@Service
public class DiscussServiceImpl extends ServiceImpl<DiscussMapper, Discuss> implements IDiscussService
{

    @Autowired
    private CacheManager cacheManager;

    @Autowired
    private ApiConfigData apiConfigData;

    @Autowired
    private IDiscussIdService discussIdService;

    @Autowired
    private IDiscussConfigService discussConfigService;

    @Autowired
    private IDiscussCommentService discussCommentService;

    @Autowired
    private IDiscussActivityService discussActivityService;

    @Autowired
    private IDiscussCategoryService discussCategoryService;

    @Autowired
    private IDiscussVoteService discussVoteService;

    @Autowired
    private IDiscussVoteOptionService discussVoteOptionService;

    @Autowired
    private IDiscussVoteRecordService discussVoteRecordService;

    @Autowired
    private IDiscussLikeService discussLikeService;

    @Autowired
    private IDiscussAsyncService discussAsyncService;


    @Resource(name=AsyncThreadPoolConfig.ASYNC_EXECUTOR_POOL_NAME)
    private ThreadPoolTaskExecutor asyncExecutor;


    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private OrgFeignClient orgFeignClient;

    @Autowired
    private ProjectFeignClient projectFeignClient;


    @Override
    public Integer initDiscuss(InitDiscussDTO params) {
        log.info("-------discuss init params:{}", JSON.toJSONString(params));
        //初始化组织相关分类
        Integer result=discussCategoryService.initDiscussCategory(params);
        return result;
    }

    @Override
    public Map<String, Boolean> isShowDiscuss(DiscussConfigQuery params) {
        Map<String, Boolean> result=new HashMap<>();
        result.put("isShow",discussConfigService.isShowDiscuss(params));
        return result;
    }

    @Override
    public Integer getTotal(String sourceId, Integer sourceType) {
        Integer total=baseMapper.getTotal(sourceId,sourceType);
        return total;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer discussSet(UpdateDiscussConfigDTO params) {
        String  currUserId=params.getCurrUserId();
        //判断权限
        Integer acessLevel=0;
        Integer sourceType=params.getSourceType();
        String sourceId=params.getSourceId();
        UserRoleDto acessParams=new UserRoleDto();
        acessParams.setCurrUserId(currUserId);
        //判断组织或项目的访问权限
        try{
            switch (sourceType){
                case 1:
                    acessParams.setOrgId(sourceId);
                    acessLevel=orgFeignClient.getOrgAccessLevel(acessParams);
                    break;
                case 2:
                    acessParams.setProjectId(sourceId);
                    acessLevel=projectFeignClient.getProjectAccessLevel(acessParams);
                    break;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("-----查询项目或组织成员的访问权限出错");
        }
        if(acessLevel<40){
            throw new BusinessException(ResultCodeEnum.UNAUTHORIZED);
        }
        //更新开关
        Integer result= discussConfigService.updateDiscussConfig(params);
        Boolean isOpen=params.getIsOpen();
        //如果打开，就去初始化discuss相关资源
        if(isOpen){
            InitDiscussDTO initParams=new InitDiscussDTO();
            initParams.setSourceId(params.getSourceId());
            initParams.setSourceType(params.getSourceType());
            initParams.setCurrUserId(params.getCurrUserId());
            discussCategoryService.initDiscussCategory(initParams);
        }
        return result;
    }

    /**
     * 分页查询讨论列表
     *
     * @param query 讨论
     * @return 讨论
     */
    @Override
    public Page<DiscussVO> findPageList(DiscussQuery query) throws Exception {
        String sourceId=query.getSourceId();
        Integer sourceType=query.getSourceType();
        if(StringUtils.isBlank(sourceId)){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"sourceId");
        }
        if(sourceType==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"sourceType");
        }
        Page<DiscussVO> result=null;
        //查询缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(query.getSourceId());
        String key=query.generateKey();
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            result = cache.get(key, Page.class);
        }catch (Exception e){
            log.info("cache get key:{} error: {} !",key,e.getMessage());
        }
        if(result!=null){
            return result;
        }
        //获得Page对象
        Page<DiscussVO> page = query.getPage();
        String currUserId=query.getCurrUserId();
        List<DiscussVO> pageList=baseMapper.findPageList(page,query);
        if(pageList!=null&&pageList.size()>0){
            List<String> userIds=new ArrayList<>();
            List<String> discussIds=new ArrayList<>();
            pageList.stream().forEach(discussVO->{
                String createBy=discussVO.getCreatedBy();
                userIds.add(createBy);
                String discussId=discussVO.getObjectId();
                discussIds.add(discussId);
            });
            Future<List<String>> taskA =asyncExecutor.submit(()->{
                //批量查询用户点赞列表
                List<String> likeRecords=new ArrayList<>();
                if(StringUtils.isNotBlank(currUserId)){
                    BatchLikeRecordQuery params=new BatchLikeRecordQuery();
                    params.setTargetType(1);
                    params.setUserId(query.getCurrUserId());
                    params.setTargetIds(discussIds);
                    likeRecords=discussLikeService.selectLikeRecordBatch(params);
                }
                return likeRecords;
            });
            Future<Map<String, UserInfoVO>> taskB =asyncExecutor.submit(()->{
                //批量查询用户信息
                Map<String, UserInfoVO> userInfoMap=new HashMap<>();
                try {
                    userInfoMap=userFeignClient.batchQuery(userIds);
                }catch (Exception e){
                    log.info("query remote user info error");
                }
                return userInfoMap;
            });
            //查询讨论分类信息
            Future<Map<String, DiscussCategoryVO>> taskC =asyncExecutor.submit(()->{
                //批量查询分类信息
                return discussCategoryService.getMapBySourceId(sourceId,sourceType);
            });
            List<String> finalLikeRecords = taskA.get();
            Map<String, UserInfoVO> finalUserInfoMap = taskB.get();
            Map<String, DiscussCategoryVO> categoryVOMap=taskC.get();
            pageList.stream().parallel().forEach(discussVO->{
                String discussId=discussVO.getObjectId();
                String createBy=discussVO.getCreatedBy();
                String categoryId=discussVO.getCategoryId();
                UserInfoVO userInfoVo = finalUserInfoMap.get(createBy);
                if(userInfoVo!=null){
                    discussVO.setCreatedByUserName(userInfoVo.getUsername());
                    discussVO.setCreatedByUserPhoto(userInfoVo.getPhoto());
                }
                if(StringUtils.isNotBlank(currUserId)&& finalLikeRecords.contains(discussId)){
                    discussVO.setIsLike(true);
                }
                DiscussCategoryVO categoryVO=categoryVOMap.get(categoryId);
                discussVO.setCategory(categoryVO);
            });
        }
        page.setRecords(pageList);
        try{
            cache.put(key, page);
        }catch (Exception e){
            log.info("cache put key:{} error: {} !",key,e.getMessage());
        }
        return page;
    }

    /**
     * 根据id查询讨论
     * 
     * @param id 讨论主键
     * @return 讨论
     */
    @Override
    public DiscussVO selectDiscussById(String id)
    {
        DiscussVO result=baseMapper.selectDiscussById(id);
       /* if(result!=null){
            //清除讨论列表缓存
            StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
            cacheName.append(result.getSourceId());
            Cache cache=null;
            try{
                cache = cacheManager.getCache(cacheName.toString());
                cache.clear();
            }catch (Exception e){
                log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
            }
        }*/
        return result;
    }

    @Override
    public DiscussVO selectDiscussDetail(DisciussDetailQuery query) {
        String currUserId=query.getCurrUserId();
        DiscussVO result=baseMapper.selectDiscussDetail(query);
        if(result==null){
            throw new BusinessException(ResultCodeEnum.RESOURCE_NOT_EXIST);
        }
        List<String> userIds=new ArrayList<>();
        String createBy=result.getCreatedBy();
        userIds.add(createBy);
        //判断是否采纳答案；
        Integer isAnswered=result.getIsAnswered();
        DiscussCommentVO discussCommentVO=null;
        if(isAnswered==1){
            //查询采纳答案的详细信息
            String answerId=result.getAnswerId();
            discussCommentVO=discussCommentService.selectDiscussCommentById(answerId);
            userIds.add(discussCommentVO.getCreatedBy());
        }
        String id=result.getObjectId();
        //查询用户信息
        try{
            Map<String, UserInfoVO> userInfoMap=userFeignClient.batchQuery(userIds);
            UserInfoVO userInfoVO=userInfoMap.get(createBy);
            if(userInfoVO!=null){
                result.setCreatedByUserName(userInfoVO.getUsername());
                result.setCreatedByUserPhoto(userInfoVO.getPhoto());
            }
            if(discussCommentVO!=null){
                UserInfoVO answerUserInfo=userInfoMap.get(discussCommentVO.getCreatedBy());
                if(answerUserInfo!=null){
                    discussCommentVO.setCreatedByUserName(userInfoVO.getUsername());
                    discussCommentVO.setCreatedByUserPhoto(userInfoVO.getPhoto());
                }
                result.setAnswerInfo(discussCommentVO);
            }
        }catch (Exception e){
            log.info("query remote user info error:userId:{}",createBy);
        }
        //查询是否点赞
        DiscussLikeRecordQuery queryLike=new DiscussLikeRecordQuery();
        queryLike.setTargetId(id);
        queryLike.setTargetType(1);
        queryLike.setUserId(currUserId);
        Boolean isLike=discussLikeService.selectLikeRecord(queryLike);
        result.setIsLike(isLike);
        //查询是否投票
        DiscussVoteRecordVO voteRecordVO= discussVoteRecordService.selectDiscussVoteRecord(DiscussVoteRecordQuery.builder().userId(currUserId).discussId(id).build());
        if(voteRecordVO!=null){
            result.setIsVote(true);
            result.setOptionId(voteRecordVO.getOptionId());
        }
        //查询讨论
        String categoryId=result.getCategoryId();
        DiscussCategoryVO discussCategory=discussCategoryService.selectDiscussCategoryById(categoryId);
        if(discussCategory!=null){
            result.setCategory(discussCategory);
            Integer categoryType=discussCategory.getCategoryType();
            if(4==categoryType){
                //当是投票类型的时候，需要查询
                DiscussVoteVO discussVoteVO=discussVoteService.selectVoteByDiscussId(id);
                result.setQuestion(discussVoteVO);
                LinkedList<DiscussVoteOptionVO> options=discussVoteOptionService.selectVoteOptionList(id);
                result.setOptions(options);
            }
        }
        return result;
    }

    /**
     * 查询讨论列表
     * 
     * @param query 讨论
     * @return 讨论
     */
    @Override
    public List<DiscussVO> selectDiscussList(DiscussQuery query)
    {
        return baseMapper.selectDiscussList(query);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer vote(DiscussVoteDTO params) {
        Integer result=0;
        boolean isRepateVote=false;
        String discussId=params.getDiscussId();
        String optionId=params.getOptionId();
        String currUserId=params.getCurrUserId();
        String oldOptionId=null; //记录原来投票选项
        DiscussVoteRecordVO discussVoteRecordVO=discussVoteRecordService.selectDiscussVoteRecord(DiscussVoteRecordQuery.builder().userId(currUserId).discussId(discussId).build());
        Integer restVoteTotal=apiConfigData.getResteVoteTotal();
        if(discussVoteRecordVO!=null&&restVoteTotal==0){
            throw new BusinessException(ResultCodeEnum.DISCUSS_VOTE_REPATE_ERROR);
        }else if(discussVoteRecordVO!=null&&restVoteTotal==1){
            String lastModifiedBy=discussVoteRecordVO.getLastModifiedBy();
            if(StringUtils.isNotBlank(lastModifiedBy)){
                throw new BusinessException(ResultCodeEnum.DISCUSS_VOTE_CHANGE_ONE_ERROR);
            }
            isRepateVote=true;
            oldOptionId=discussVoteRecordVO.getOptionId();
        }if(discussVoteRecordVO!=null){
            isRepateVote=true;
            oldOptionId=discussVoteRecordVO.getOptionId();
        }

        DiscussVO discussVO=baseMapper.selectDiscussById(discussId);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"discussId");
        }
        //判断讨论状态，如果关闭，禁止用户投票操作
        Integer isClosed=discussVO.getIsClosed();
        if(isClosed>0){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CLOSE_ERROR);
        }
        //如果讨论被锁定，则判断当前用户是否是组织或者项目成员，如果是组织成员可以修改和投票
        Integer isLocked=discussVO.getIsLock();
        Integer sourceType=discussVO.getSourceType();
        String sourceId=discussVO.getSourceId();
        if(isLocked==1){
            Integer acessLevel=0;
            UserRoleDto acessParams=new UserRoleDto();
            acessParams.setCurrUserId(currUserId);
            //判断组织或项目的访问权限
            try{
                switch (sourceType){
                    case 1:
                        acessParams.setOrgId(sourceId);
                        acessLevel=orgFeignClient.getOrgAccessLevel(acessParams);
                        break;
                    case 2:
                        acessParams.setProjectId(sourceId);
                        acessLevel=projectFeignClient.getProjectAccessLevel(acessParams);
                        break;
                }
            }catch (Exception e){
                e.printStackTrace();
                log.error("-----查询项目或组织成员的访问权限出错");
            }
            if(acessLevel<10){
                throw new BusinessException(ResultCodeEnum.DISCUSS_LOCK_ERROR);
            }
        }
        String categoryId=discussVO.getCategoryId();
        DiscussCategoryVO discussCategory=discussCategoryService.selectDiscussCategoryById(categoryId);
        if(discussCategory!=null){
            Integer categoryType=discussCategory.getCategoryType();
            if(4==categoryType){
                //当是投票类型的时候，需要查询
                DiscussVoteVO discussVoteVO=discussVoteService.selectVoteByDiscussId(discussId);
                if(discussVoteVO==null){
                    throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"discussId");
                }
                DiscussVoteOptionVO discussVoteOptionVO=discussVoteOptionService.selectDiscussVoteOptionById(optionId);
                if(discussVoteOptionVO==null){
                    throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"optionId");
                }

                if(isRepateVote){
                    //重复投票，修改投票选项
                    UpdateDiscussVoteRecordDTO updaetRecordParams=new UpdateDiscussVoteRecordDTO();
                    updaetRecordParams.setDiscussId(discussId);
                    updaetRecordParams.setVoteId(discussVoteVO.getObjectId());
                    updaetRecordParams.setOptionId(optionId);
                    updaetRecordParams.setUserId(currUserId);
                    updaetRecordParams.setOldOptionId(oldOptionId);
                    result=discussVoteRecordService.updateDiscussVoteRecord(updaetRecordParams);
                }else{
                    //第一次投票，插入投票记录
                    NewDiscussVoteRecordDTO newRecordParams=new NewDiscussVoteRecordDTO();
                    newRecordParams.setDiscussId(discussId);
                    newRecordParams.setVoteId(discussVoteVO.getObjectId());
                    newRecordParams.setOptionId(optionId);
                    newRecordParams.setUserId(currUserId);
                    result=discussVoteRecordService.insertDiscussVoteRecord(newRecordParams);
                }
            }
        }
        //清除讨论列表缓存
        StringBuilder cacheName=null;
        try{
            cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
            cacheName.append(sourceId);
            Cache cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        //发送投票活动
        BaseActivityDTO voteActivity=new BaseActivityDTO();
        voteActivity.setDiscussId(discussId);
        voteActivity.setSourceId(sourceId);
        voteActivity.setActionUid(currUserId);
        voteActivity.setSourceType(sourceType);
        DiscussActivityEventDTO eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.VOTE_DISCUSS,voteActivity);
        discussActivityService.sendDiscussActivity(eventDTO);
        return result;
    }

    @Override
    public Integer addLabel(DiscussLabelDTO params) {
        //先查询disscuss
        String discussId=params.getDiscussId();
        String currUserId=params.getCurrUserId();
        DiscussVO discussVO=baseMapper.selectDiscussById(discussId);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"discussId");
        }
        //判断权限
        Integer acessLevel=0;
        Integer sourceType=discussVO.getSourceType();
        String sourceId=discussVO.getSourceId();
        UserRoleDto acessParams=new UserRoleDto();
        acessParams.setCurrUserId(currUserId);
        //判断组织或项目的访问权限
        try{
            switch (sourceType){
                case 1:
                    acessParams.setOrgId(sourceId);
                    acessLevel=orgFeignClient.getOrgAccessLevel(acessParams);
                    break;
                case 2:
                    acessParams.setProjectId(sourceId);
                    acessLevel=projectFeignClient.getProjectAccessLevel(acessParams);
                    break;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("-----查询项目或组织成员的访问权限出错");
        }
        if(acessLevel<30){
            throw new BusinessException(ResultCodeEnum.UNAUTHORIZED);
        }
        List<String> label=params.getLabel();
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, discussId);
        Discuss discuss=new Discuss();
        discuss.setLabel(label);
        discuss.setLastModifiedBy(params.getCurrUserId());
        int result=baseMapper.update(discuss,updateWrapper);
        //清除讨论列表缓存
        StringBuilder cacheName=null;
        try{
            cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
            cacheName.append(sourceId);
            Cache cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    /**
     * 新增讨论
     *
     * @param params 讨论
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String,String> insertDiscuss(NewDiscussDTO params)
    {
        Map<String,String> result=new HashMap<>();
        String categoryId=params.getCategoryId();
        DiscussCategoryVO discussCategory=discussCategoryService.selectDiscussCategoryById(categoryId);
        if(discussCategory==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"categoryId");
        }
        Integer categoryType=discussCategory.getCategoryType();
        /** 投票内容 */
        String question=params.getQuestion();
        /** 投票选项 */
        LinkedList<String> options=params.getOptions();
        //参数检查
        if(4==categoryType){
            if(StringUtils.isBlank(question)){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"question");
            }
            if(options==null||options.size()==0){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"options");
            }
        }
        String sourceId=params.getSourceId();
        Integer sourceType=params.getSourceType();
        String currUserId=params.getCurrUserId();
        Discuss discuss=new Discuss();
        BeanUtils.copyProperties(params,discuss);
        String id= IdUtil.fastSimpleUUID();
        discuss.setObjectId(id);
        discuss.setCreatedBy(currUserId);
        Integer serialNumber=discussIdService.getMaxId(sourceId,1);
        discuss.setSerialNumber(serialNumber);
        int total=baseMapper.insert(discuss);
        //如果为投票类型，则保存投票相关信息
        if(total>0&&4==categoryType){
            //保存投票问题
            NewDiscussVoteDTO voteParams=new NewDiscussVoteDTO();
            voteParams.setDiscussId(id);
            voteParams.setQuestion(question);
            voteParams.setCurrUserId(currUserId);
            String voteId=discussVoteService.insertDiscussVote(voteParams);
            //保存投票选项
            NewDiscussVoteOptionDTO optionParams=new NewDiscussVoteOptionDTO();
            optionParams.setDiscussId(id);
            optionParams.setVoteId(voteId);
            optionParams.setOptions(options);
            optionParams.setCurrUserId(currUserId);
            discussVoteOptionService.addBatch(optionParams);
        }
        result.put("id",id);
        result.put("serialNumber",serialNumber.toString());
        //清除讨论列表缓存
        StringBuilder cacheName=null;
        try{
            cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
            cacheName.append(sourceId);
            Cache cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    /**
     * 修改讨论
     *
     * @param params 讨论
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateDiscuss(UpdateDiscussDTO params)
    {
        String id=params.getId();
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        String categoryId=discussVO.getCategoryId();
        DiscussCategoryVO discussCategory=discussCategoryService.selectDiscussCategoryById(categoryId);
        if(discussCategory==null){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CATEGORY_NO_EXIST_ERROR);
        }
        Integer categoryType=discussCategory.getCategoryType();
        /** 投票内容 */
        String question=params.getQuestion();
        /** 投票选项 */
        LinkedList<String> options=params.getOptions();
        //参数检查
        if(4==categoryType&&params.getIsEdit()){
            if(StringUtils.isBlank(question)){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"question");
            }
            if(options==null||options.size()==0){
                throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"options");
            }
        }
        String sourceId=discussVO.getSourceId();
        String currUserId=params.getCurrUserId();
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, id);
        Discuss discuss=new Discuss();
        BeanUtils.copyProperties(params,discuss);
        discuss.setLastModifiedBy(currUserId);
        int result=baseMapper.update(discuss,updateWrapper);
        //如果投票选项编辑，则删除所有discuss相关投票数据，重新初始化
        if(result>0&&4==categoryType&&params.getIsEdit()){
            //先清除投票相关的信息
            discussVoteService.deleteVoteByDiscussId(id);
            //保存投票信息
            //保存投票问题
            NewDiscussVoteDTO voteParams=new NewDiscussVoteDTO();
            voteParams.setDiscussId(id);
            voteParams.setQuestion(question);
            voteParams.setCurrUserId(currUserId);
            String voteId=discussVoteService.insertDiscussVote(voteParams);
            //保存投票选项
            NewDiscussVoteOptionDTO optionParams=new NewDiscussVoteOptionDTO();
            optionParams.setDiscussId(id);
            optionParams.setVoteId(voteId);
            optionParams.setOptions(options);
            optionParams.setCurrUserId(currUserId);
            discussVoteOptionService.addBatch(optionParams);
        }
        //清除讨论列表缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(sourceId);
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer changeCategory(ChangeCategoryDTO params) {
        String id=params.getId();
        String currUserId=params.getCurrUserId();
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        //判断权限
        Integer acessLevel=0;
        Integer sourceType=discussVO.getSourceType();
        String sourceId=discussVO.getSourceId();
        UserRoleDto acessParams=new UserRoleDto();
        acessParams.setCurrUserId(currUserId);
        //判断组织或项目的访问权限
        try{
            switch (sourceType){
                case 1:
                    acessParams.setOrgId(sourceId);
                    acessLevel=orgFeignClient.getOrgAccessLevel(acessParams);
                    break;
                case 2:
                    acessParams.setProjectId(sourceId);
                    acessLevel=projectFeignClient.getProjectAccessLevel(acessParams);
                    break;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("-----查询项目或组织成员的访问权限出错");
        }
        if(acessLevel<30){
            throw new BusinessException(ResultCodeEnum.UNAUTHORIZED);
        }
        String oldCategoryId=discussVO.getCategoryId();
        DiscussCategoryVO oldDiscussCategoryVO=discussCategoryService.selectDiscussCategoryById(oldCategoryId);
        Integer oldCategoryType=null;
        if(oldDiscussCategoryVO!=null){
            //判断是否是投票类型
            oldCategoryType=oldDiscussCategoryVO.getCategoryType();
        }
        String categoryId=params.getCategoryId();
        //根据categoryId判断分类是否存在
        DiscussCategoryVO discussCategoryVO=discussCategoryService.selectDiscussCategoryById(categoryId);
        if(discussCategoryVO==null||!sourceId.equals(discussCategoryVO.getSourceId())){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"categoryId");
        }
        Integer newCategoryType=discussCategoryVO.getCategoryType();
        if(oldCategoryType==4&&newCategoryType!=4){
            throw new BusinessException(ResultCodeEnum.DISCUSS_POLL_DISABLE_CHANGE_ERROR);
        }
        if(oldCategoryType!=4&&newCategoryType==4){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CATEGORY_CHANGE_POLL_ERROR);
        }
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, id);
        Discuss discuss=new Discuss();
        discuss.setCategoryId(categoryId);
        discuss.setLastModifiedBy(currUserId);
        int result=baseMapper.update(discuss,updateWrapper);
        //清除讨论列表缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(sourceId);
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer changeLock(ChangeLockDTO params) {
        String id=params.getId();
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        String sourceId=discussVO.getSourceId();
        Integer sourceType=discussVO.getSourceType();
        String currUserId=params.getCurrUserId();
        //判断权限
        Integer acessLevel=0;
        UserRoleDto acessParams=new UserRoleDto();
        acessParams.setCurrUserId(currUserId);
        //判断组织或项目的访问权限
        try{
            switch (sourceType){
                case 1:
                    acessParams.setOrgId(sourceId);
                    acessLevel=orgFeignClient.getOrgAccessLevel(acessParams);
                    break;
                case 2:
                    acessParams.setProjectId(sourceId);
                    acessLevel=projectFeignClient.getProjectAccessLevel(acessParams);
                    break;
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("-----查询项目或组织成员的访问权限出错");
        }
        if(acessLevel<40){
            throw new BusinessException(ResultCodeEnum.UNAUTHORIZED);
        }
        Integer isLock=params.getIsLock();
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, id);
        Discuss discuss=new Discuss();
        discuss.setIsLock(isLock);
        discuss.setLastModifiedBy(currUserId);
        int result=baseMapper.update(discuss,updateWrapper);
        UpdateStateActivityDTO udapateActivity=new UpdateStateActivityDTO();
        udapateActivity.setDiscussId(id);
        udapateActivity.setSourceId(sourceId);
        udapateActivity.setActionUid(currUserId);
        udapateActivity.setSourceType(sourceType);
        DiscussActivityEventDTO eventDTO=null;
        if(isLock==1){
            udapateActivity.setState(DiscussStateEnum.LOCK);
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.LOCK,udapateActivity);
        }else{
            udapateActivity.setState(DiscussStateEnum.UN_LOCK);
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.UN_LOCK,udapateActivity);
        }
        discussActivityService.sendDiscussActivity(eventDTO);
        //清除讨论列表缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(sourceId);
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer changePin(ChangePinDTO params) {
        String id=params.getId();
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        String sourceId=discussVO.getSourceId();
        Integer sourceType=discussVO.getSourceType();
        String currUserId=params.getCurrUserId();
        //判断组织或项目的管理员权限
        switch (sourceType){
            case 1:
                break;
            case 2:
                break;
        }
        Integer isPin=params.getIsPin();
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, id);
        updateWrapper.set(Discuss::getIsPin, isPin);
        int result=0;
        BaseActivityDTO udapateActivity=new BaseActivityDTO();
        udapateActivity.setDiscussId(id);
        udapateActivity.setSourceId(sourceId);
        udapateActivity.setActionUid(currUserId);
        udapateActivity.setSourceType(sourceType);
        DiscussActivityEventDTO eventDTO=null;
        if(isPin==1){
            updateWrapper.set(Discuss::getPinDate, new Date());
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.PIN,udapateActivity);
        }else{
            updateWrapper.set(Discuss::getPinDate, null);
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.UN_PIN,udapateActivity);
        }
        result=baseMapper.update(null,updateWrapper);
        discussActivityService.sendDiscussActivity(eventDTO);
        //清除讨论列表缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(sourceId);
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer changeCategoryPin(ChangePinDTO params) {
        String id=params.getId();
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        String sourceId=discussVO.getSourceId();
        Integer sourceType=discussVO.getSourceType();
        String currUserId=params.getCurrUserId();
        String categoryId=discussVO.getCategoryId();
        //根据categoryId判断分类是否存在
        DiscussCategoryVO discussCategoryVO=discussCategoryService.selectDiscussCategoryById(categoryId);
        if(discussCategoryVO==null){
            throw new BusinessException(ResultCodeEnum.DISCUSS_CATEGORY_NO_EXIST_ERROR);
        }
        Integer isPin=params.getIsPin();
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, id);
        updateWrapper.set(Discuss::getIsCategoryPin, isPin);
        BaseActivityDTO udapateActivity=new BaseActivityDTO();
        udapateActivity.setDiscussId(id);
        udapateActivity.setSourceId(sourceId);
        udapateActivity.setActionUid(currUserId);
        udapateActivity.setSourceType(sourceType);
        DiscussActivityEventDTO eventDTO=null;
        if(isPin==1){
            updateWrapper.set(Discuss::getPinCategoryDate, new Date());
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.PIN_CATEGORY,udapateActivity);
        }else{
            updateWrapper.set(Discuss::getPinCategoryDate, null);
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.UN_PIN_CATEGORY,udapateActivity);
        }
        int result=baseMapper.update(null,updateWrapper);
        discussActivityService.sendDiscussActivity(eventDTO);
        //清除讨论列表缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(sourceId);
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
            StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
            myDiscussCacheName.append(currUserId);
            StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
            myJoinDiscussCacheName.append(currUserId);
            Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myDiscussCache.clear();
            Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
            myJoinDiscussCache.clear();
        }catch (Exception e){
            log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
        }
        return result;
    }

    @Override
    public Integer changeState(ChangeStateDTO params) {
        String id=params.getId();
        String currUserId=params.getCurrUserId();
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        String createdBy=discussVO.getCreatedBy();
        String sourceId=discussVO.getSourceId();
        Integer sourceType=discussVO.getSourceType();
        //不是本人创建，需要判断权限
        if(!createdBy.equals(currUserId)){
            //判断权限
            Integer acessLevel=0;
            UserRoleDto acessParams=new UserRoleDto();
            acessParams.setCurrUserId(currUserId);
            //判断组织或项目的访问权限
            try{
                switch (sourceType){
                    case 1:
                        acessParams.setOrgId(sourceId);
                        acessLevel=orgFeignClient.getOrgAccessLevel(acessParams);
                        break;
                    case 2:
                        acessParams.setProjectId(sourceId);
                        acessLevel=projectFeignClient.getProjectAccessLevel(acessParams);
                        break;
                }
            }catch (Exception e){
                e.printStackTrace();
                log.error("-----查询项目或组织成员的访问权限出错");
            }
            if(acessLevel<20){
                throw new BusinessException(ResultCodeEnum.UNAUTHORIZED);
            }
        }
        Integer isClose=params.getState();
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, id);
        updateWrapper.set(Discuss::getIsClosed, isClose);
        updateWrapper.set(Discuss::getLastModifiedBy,currUserId);
        //发送关闭或者打开事件
        UpdateStateActivityDTO udapateActivity=new UpdateStateActivityDTO();
        udapateActivity.setDiscussId(id);
        udapateActivity.setSourceId(sourceId);
        udapateActivity.setActionUid(currUserId);
        udapateActivity.setSourceType(sourceType);
        DiscussActivityEventDTO eventDTO=null;
        if(isClose==0){
            udapateActivity.setState(DiscussStateEnum.OPEN);
            updateWrapper.set(Discuss::getClosedDate, null);
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.OPEN,udapateActivity);
        }else{
            udapateActivity.setState(DiscussStateEnum.CLOSE);
            updateWrapper.set(Discuss::getClosedDate, new Date());
            eventDTO=DiscussActivityEventDTO.build(DiscussActionEventEnum.CLOSE,udapateActivity);
        }
        int result=baseMapper.update(null,updateWrapper);
        if(result>0){
            discussActivityService.sendDiscussActivity(eventDTO);
            //清除讨论列表缓存
            StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
            cacheName.append(sourceId);
            Cache cache=null;
            try{
                cache = cacheManager.getCache(cacheName.toString());
                cache.clear();
                StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
                myDiscussCacheName.append(currUserId);
                StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
                myJoinDiscussCacheName.append(currUserId);
                Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
                myDiscussCache.clear();
                Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
                myJoinDiscussCache.clear();
            }catch (Exception e){
                log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
            }
        }
        return result;
    }

    @Override
    public Integer transfer(TransferDTO params) {
        //TODO discuss讨论转移功能待开发
        return null;
    }

    /**
     * 删除讨论信息
     * 
     * @param params 删除讨论的请求参数
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteDiscussById(DeleteResourceDTO params)
    {
        String id=params.getId();
        String currUserId=params.getCurrUserId();
        LambdaQueryWrapper<Discuss> queryWrapper = new LambdaQueryWrapper<Discuss>();
        queryWrapper.eq(Discuss::getObjectId, params.getId());
        int result=baseMapper.delete(queryWrapper);
        if(result>0){
            //异步删除关联的评论
            discussAsyncService.deleteDiscussRelateByDiscussId(id);
            String sourceId=params.getSourceId();
            if(StringUtils.isNotBlank(sourceId)){
                StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
                cacheName.append(sourceId);
                Cache cache=null;
                try{
                    cache = cacheManager.getCache(cacheName.toString());
                    cache.clear();
                    StringBuilder myDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
                    myDiscussCacheName.append(currUserId);
                    StringBuilder myJoinDiscussCacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
                    myJoinDiscussCacheName.append(currUserId);
                    Cache myDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
                    myDiscussCache.clear();
                    Cache myJoinDiscussCache = cacheManager.getCache(myDiscussCacheName.toString());
                    myJoinDiscussCache.clear();
                }catch (Exception e){
                    log.info("cache evict cache name:{} error: {} !",cacheName.toString(),e.getMessage());
                }
            }
        }
        return  result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateCommentTotal(String discussId, Integer sum) {
        return baseMapper.updateCommentTotal(discussId,sum);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Integer updateReplyTotal(String discussId, Integer sum) {
        return baseMapper.updateReplyTotal(discussId,sum);
    }

    @Override
    public void transferCategory(TransferCategoryDTO params) {
        baseMapper.transferCategory(params);
    }

    @Override
    public Set<UserInfoVO> relateUser(String id) {
        DiscussVO discussVO=baseMapper.selectDiscussById(id);
        if(discussVO==null){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,"id");
        }
        Integer sourceType=discussVO.getSourceType();
        String sourceId=discussVO.getSourceId();
        //判断组织或项目的管理员权限
        List<UserInfoVO> member=null;
        switch (sourceType){
            case 1:
                //获取组织成员
                member=orgFeignClient.getOrgMemberAll(sourceId);
                break;
            case 2:
                //获取项目成员
                member=projectFeignClient.getProjectMemberAll(sourceId);
                break;
        }
        Set<UserInfoVO> result=new HashSet<>(member);
        //批量查询discuss关联用户信息
        List<String> userIds=discussActivityService.selectRecentRelateUser(id);
        Map<String, UserInfoVO> userInfoMap=userFeignClient.batchQuery(userIds);
        userInfoMap.forEach((key,value)->{
            result.add(value);
        });
        return result;
    }

    @Override
    public List<UserInfoVO> recentActivity(String id) {
        //查询最近活动的用户
        List<UserInfoVO> result=new LinkedList<>();
        //批量查询discuss关联用户信息
        List<String> userIds=discussActivityService.selectRecentRelateUser(id);
        try {
            Map<String, UserInfoVO> userInfoMap=userFeignClient.batchQuery(new ArrayList<>(userIds));
            userIds.forEach(userId->{
                UserInfoVO userInfoVO=userInfoMap.get(userId);
                result.add(userInfoVO);
            });
        }catch (Exception e){
            log.info("-------batch query user info error!");
        }
        return result;
    }

    @Override
    public Integer like(DiscussLikeDTO params) {
        String userId=params.getUserId();
        if(StringUtils.isBlank(userId)){
            return 0;
        }
        discussAsyncService.like(params);
        return 1;
    }

    @Override
    public Integer unLike(DiscussLikeDTO params) {
        String userId=params.getUserId();
        if(StringUtils.isBlank(userId)){
            return 0;
        }
        discussAsyncService.unLike(params);
        return 1;
    }

    @Override
    public Integer updateAuditStatus(UpdateAuditStatusDTO params) {
        LambdaUpdateWrapper<Discuss> updateWrapper = new UpdateWrapper<Discuss>().lambda();
        updateWrapper.eq(Discuss::getObjectId, params.getId());
        updateWrapper.set(Discuss::getAuditStatus, params.getAuditStatus());
        int result=baseMapper.update(null,updateWrapper);
        return result;
    }

    @Override
    public Page<DiscussVO> myDiscussPageList(DiscussQuery query) throws Exception {
        String currUserId=query.getCurrUserId();
        if(StringUtils.isBlank(currUserId)){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,currUserId);
        }
        Page<DiscussVO> result=null;
        //查询缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_MY_LIST_PAGE);
        cacheName.append(currUserId);
        String key=query.generateKey();
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            result = cache.get(key, Page.class);
        }catch (Exception e){
            log.info("cache get key:{} error: {} !",key,e.getMessage());
        }
        if(result!=null){
            return result;
        }
        //获得Page对象
        Page<DiscussVO> page = query.getPage();
        List<DiscussVO> pageList=baseMapper.myDiscussPageList(page,query);
        if(pageList!=null&&pageList.size()>0){
            List<String> userIds=new ArrayList<>();
            List<String> discussIds=new ArrayList<>();
            pageList.stream().forEach(discussVO->{
                String createBy=discussVO.getCreatedBy();
                userIds.add(createBy);
                String discussId=discussVO.getObjectId();
                discussIds.add(discussId);
            });
            Future<List<String>> taskA =asyncExecutor.submit(()->{
                //批量查询用户点赞列表
                List<String> likeRecords=new ArrayList<>();
                if(StringUtils.isNotBlank(currUserId)){
                    BatchLikeRecordQuery params=new BatchLikeRecordQuery();
                    params.setTargetType(1);
                    params.setUserId(query.getCurrUserId());
                    params.setTargetIds(discussIds);
                    likeRecords=discussLikeService.selectLikeRecordBatch(params);
                }
                return likeRecords;
            });
            Future<Map<String, UserInfoVO>> taskB =asyncExecutor.submit(()->{
                //批量查询用户信息
                Map<String, UserInfoVO> userInfoMap=new HashMap<>();
                try {
                    userInfoMap=userFeignClient.batchQuery(userIds);
                }catch (Exception e){
                    log.info("query remote user info error");
                }
                return userInfoMap;
            });
            List<String> finalLikeRecords = taskA.get();
            Map<String, UserInfoVO> finalUserInfoMap = taskB.get();
            pageList.stream().parallel().forEach(discussVO->{
                String discussId=discussVO.getObjectId();
                String createBy=discussVO.getCreatedBy();
                String categoryId=discussVO.getCategoryId();
                UserInfoVO userInfoVo = finalUserInfoMap.get(createBy);
                if(userInfoVo!=null){
                    discussVO.setCreatedByUserName(userInfoVo.getUsername());
                    discussVO.setCreatedByUserPhoto(userInfoVo.getPhoto());
                }
                if(StringUtils.isNotBlank(currUserId)&& finalLikeRecords.contains(discussId)){
                    discussVO.setIsLike(true);
                }
                /*DiscussCategoryVO categoryVO=categoryVOMap.get(categoryId);
                discussVO.setCategory(categoryVO);*/
            });
        }
        page.setRecords(pageList);
        try{
            cache.put(key, page);
        }catch (Exception e){
            log.info("cache put key:{} error: {} !",key,e.getMessage());
        }
        return page;
    }

    @Override
    public Page<DiscussVO> joinDiscussPageList(DiscussQuery query) throws Exception {
        String currUserId=query.getCurrUserId();
        if(StringUtils.isBlank(currUserId)){
            throw new BusinessException(ResultCodeEnum.PARAMETER_ERROR_CUSTOM,currUserId);
        }
        Page<DiscussVO> result=null;
        //查询缓存
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_JOIN_LIST_PAGE);
        cacheName.append(currUserId);
        String key=query.generateKey();
        Cache cache=null;
        try{
            cache = cacheManager.getCache(cacheName.toString());
            result = cache.get(key, Page.class);
        }catch (Exception e){
            log.info("cache get key:{} error: {} !",key,e.getMessage());
        }
        if(result!=null){
            return result;
        }
        //获得Page对象
        Page<DiscussVO> page = query.getPage();
        List<DiscussVO> pageList=baseMapper.joinDiscussPageList(page,query);
        if(pageList!=null&&pageList.size()>0){
            List<String> userIds=new ArrayList<>();
            List<String> discussIds=new ArrayList<>();
            pageList.stream().forEach(discussVO->{
                String createBy=discussVO.getCreatedBy();
                userIds.add(createBy);
                String discussId=discussVO.getObjectId();
                discussIds.add(discussId);
            });
            Future<List<String>> taskA =asyncExecutor.submit(()->{
                //批量查询用户点赞列表
                List<String> likeRecords=new ArrayList<>();
                if(StringUtils.isNotBlank(currUserId)){
                    BatchLikeRecordQuery params=new BatchLikeRecordQuery();
                    params.setTargetType(1);
                    params.setUserId(query.getCurrUserId());
                    params.setTargetIds(discussIds);
                    likeRecords=discussLikeService.selectLikeRecordBatch(params);
                }
                return likeRecords;
            });
            Future<Map<String, UserInfoVO>> taskB =asyncExecutor.submit(()->{
                //批量查询用户信息
                Map<String, UserInfoVO> userInfoMap=new HashMap<>();
                try {
                    userInfoMap=userFeignClient.batchQuery(userIds);
                }catch (Exception e){
                    log.info("query remote user info error");
                }
                return userInfoMap;
            });
            List<String> finalLikeRecords = taskA.get();
            Map<String, UserInfoVO> finalUserInfoMap = taskB.get();
            pageList.stream().parallel().forEach(discussVO->{
                String discussId=discussVO.getObjectId();
                String createBy=discussVO.getCreatedBy();
                String categoryId=discussVO.getCategoryId();
                UserInfoVO userInfoVo = finalUserInfoMap.get(createBy);
                if(userInfoVo!=null){
                    discussVO.setCreatedByUserName(userInfoVo.getUsername());
                    discussVO.setCreatedByUserPhoto(userInfoVo.getPhoto());
                }
                if(StringUtils.isNotBlank(currUserId)&& finalLikeRecords.contains(discussId)){
                    discussVO.setIsLike(true);
                }
            });
        }
        page.setRecords(pageList);
        try{
            cache.put(key, page);
        }catch (Exception e){
            log.info("cache put key:{} error: {} !",key,e.getMessage());
        }
        return page;
    }

    @Override
    @Async(AsyncThreadPoolConfig.ASYNC_EXECUTOR_POOL_NAME)
    public void syncDelete(SyncDeleteDTO params) throws Exception {

        //删除讨论
        String sourceId=params.getSourceId();
        //Integer sourceType=params.getSourceType();
        int result=baseMapper.syncDelete(params);
        //删除关联评论
        discussCommentService.syncDelete(params);
        StringBuilder cacheName = new StringBuilder(RedisConstants.DISCUSS_LIST_PAGE);
        cacheName.append(sourceId);
        Cache cache=null;
        try {
            cache = cacheManager.getCache(cacheName.toString());
            cache.clear();
        }catch (Exception e){
            log.error("sync delete  sourceId:{} cache error",sourceId);
        }
        log.info("sync delete discuss sourceId:{} total:{}",sourceId,result);
    }

    @Override
    public DiscussVO selectBySourceIdAndNumber(String sourceId,Integer sourceType, Integer serialNumber){
        return baseMapper.selectDiscussDetail(DisciussDetailQuery.builder().sourceId(sourceId).sourceType(sourceType).serialNumber(serialNumber).build());
    }

}
